# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: Jongu

from coin.base.timestamp import get_timestamp


class OrderGatewayFresh(object):
  def __init__(self):
    self.reset()

  @property
  def fresh(self):
    return self._fresh

  def is_fresh(self):
    return self._fresh

  def reset(self):
    self._fresh_count = 0
    self._fresh_timestamp = None
    self._fresh = False

  def check_fresh(self):
    raise NotImplementedError()


class PositionOrderGatewayFresh(OrderGatewayFresh):
  def reset(self):
    OrderGatewayFresh.reset(self)
    self._private_count = 0
    self._private_timestamp = None
    self._balance_count = 0
    self._balance_timestamp = None
    self._position_count = 0
    self._position_timestamp = None
    self._orders_count = 0
    self._orders_timestamp = None
    self._fills_count = 0
    self._fills_timestamp = None

  def set_private_timestamp(self, timestamp=None):
    timestamp = timestamp or get_timestamp()
    self._private_count += 1
    self._private_timestamp = timestamp

  def set_balance_timestamp(self, timestamp=None):
    timestamp = timestamp or get_timestamp()
    self.set_private_timestamp(timestamp)
    self._balance_count += 1
    self._balance_timestamp = timestamp

  def set_position_timestamp(self, timestamp=None):
    timestamp = timestamp or get_timestamp()
    self.set_private_timestamp(timestamp)
    self._position_count += 1
    self._position_timestamp = timestamp

  def set_balance_position_timestamp(self, timestamp=None):
    timestamp = timestamp or get_timestamp()
    self.set_balance_timestamp(timestamp)
    self.set_position_timestamp(timestamp)

  def set_orders_timestamp(self, timestamp=None):
    timestamp = timestamp or get_timestamp()
    self.set_private_timestamp(timestamp)
    self._orders_count += 1
    self._orders_timestamp = timestamp

  def set_fills_timestamp(self, timestamp=None):
    timestamp = timestamp or get_timestamp()
    self.set_private_timestamp(timestamp)
    self._fills_count += 1
    self._fills_timestamp = timestamp

  def check_fresh(self, timestamp=None):
    timestamp = timestamp or get_timestamp()
    self._fresh_count += 1
    self._fresh_timestamp = timestamp

    fresh = True

    time_diff = abs((self._orders_timestamp or 0) - (self._fills_timestamp or 0))
    if time_diff > 30 * 1e9:
      fresh = False

    self._fresh = fresh

    return fresh


class PerProductPositionOrderGatewayFresh(OrderGatewayFresh):
  def __init__(self, products):
    self._products = products
    super().__init__()

  def reset(self):
    OrderGatewayFresh.reset(self)
    self._overall = PositionOrderGatewayFresh()
    self._per = {}
    for product in self._products:
      self._per[product] = PositionOrderGatewayFresh()

  def overall(self):
    return self._overall

  def per(self, product):
    return self._per[product]

  def check_fresh(self, timestamp=None):
    timestamp = timestamp or get_timestamp()
    self._fresh_count += 1
    self._fresh_timestamp = timestamp

    fresh = True

    fresh &= self.overall().check_fresh(timestamp)
    for key, value in self._per.items():
      fresh &= value.check_fresh(timestamp)

    self._fresh = fresh

    return fresh
